<script setup lang="ts">
import { ref, watch } from 'vue'
import { apiSearchType, apiInterfaceView } from '@renderer/api/bilibili'
import ContextMenu from '@renderer/components/ContextMenu.vue'
import chalk from 'chalk'
import { useRouter } from 'vue-router'
import { formatSeconds, storageLocal } from '@renderer/tools/index'
import CatList from '@renderer/components/CatList.vue'
import CatListItem from '@renderer/components/CatListItem.vue'
import CatImage from '@renderer/components/CatImage.vue'
import { useFavoriteStore } from '@renderer/stores/favorite'
import { usePlayerStore } from '@renderer/stores/player'

import type { TrackInfo, AlbumInfo, AlbumTrackData } from '@renderer/views/track/type'

defineOptions({ name: 'Search' })

interface SearchInfo {
  bvid: string
  cover: string
  title: string
  author: string
  authormid: number
  duration: number
}

// 江序槐晚
const props = defineProps({
  keyword: { type: String, default: '' }
})
const contextMenuRef = ref<InstanceType<typeof ContextMenu>>()
const searchData = ref<SearchInfo[]>([])
const blueBold = chalk.blueBright.bold
const router = useRouter()
const { addPlaylist } = useFavoriteStore()
const { setPlayerList, loadAudio } = usePlayerStore()

watch(
  () => props.keyword,
  async (keyword) => {
    if (!keyword && !searchData.value.length) {
      keyword = 'playlist'
    }
    if (keyword) {
      await getSearchData(keyword)
    }
  },
  {
    immediate: true
  }
)

async function getSearchData(keyword: string) {
  const { data, code } = await apiSearchType({
    keyword,
    tids: 3, // 代表音乐分区
    page: 1,
    page_size: 40,
    search_type: 'video'
  })
  console.log(blueBold(`搜索《${keyword}》===>`), data.result)
  if (code === 0) {
    const list = (data.result as any[]).map((m: Record<string, any>): SearchInfo => {
      const time = m.duration.split(':')
      const duration = time[0] * 60 + time[1] * 1
      // 接口的title字段内容会有带有em标签，需要清除
      let title: string = m.title
      let e: HTMLElement | null = document.createElement('div')
      e.innerHTML = title
      title = e.innerText
      e = null
      return {
        bvid: m.bvid,
        cover: 'https:' + m.pic,
        title,
        author: m.author,
        authormid: m.mid,
        duration
      }
    })
    searchData.value = list
  }
}

async function doPlay(bvid: string) {
  const trackData = await generateTrackData(bvid)
  if (trackData) {
    setPlayerList(trackData.tracks)
    const { bvid, cid } = trackData.tracks[0]
    await loadAudio({ bvid, cid })
  }
}

async function doTitle(bvid: string) {
  const trackData = await generateTrackData(bvid)
  if (trackData) {
    storageLocal().setItem('track-album', trackData)
    router.push({ name: 'track-album' })
  }
}

async function generateTrackData(bvid: string) {
  const { code, data } = await apiInterfaceView({ bvid })
  if (code === 0) {
    const info: AlbumInfo = {
      cover: data.pic,
      title: data.title,
      author: data.owner.name,
      pubdate: data.pubdate,
      description: data.desc,
      songcount: data.videos,
      duration: data.duration
    }

    const tracks = (data.pages as any[]).map((item: Record<string, any>) => {
      let cover = item.first_frame || data.pic
      cover = cover.replace(/^http:/i, 'https:')
      const track: TrackInfo = {
        bvid: data.bvid,
        cid: item.cid,
        cover,
        title: item.part || data.title,
        author: data.owner.name,
        duration: item.duration
      }
      return track
    })

    // 专辑里只有一首歌时，歌名有些会出现空值或者纯数字
    if (tracks.length === 1) {
      tracks[0].title = data.title
    }

    const trackData: AlbumTrackData = { info, tracks }
    return trackData
  }
  return null
}

async function doAuthor(mid: number) {
  router.push({
    name: 'track-artist',
    params: { mid }
  })
}

async function addToOwnPlay(bvid: string) {
  const trackData = await generateTrackData(bvid)
  if (trackData) {
    addPlaylist(trackData)
  }
}
</script>

<template>
  <ContextMenu ref="contextMenuRef" v-slot="{ data }: { data: SearchInfo }">
    <div class="item" @click="addToOwnPlay(data.bvid)">添加到歌单</div>
  </ContextMenu>
  <CatList :data-source="searchData" row-key="avid">
    <template #default="{ item }: { item: SearchInfo }">
      <CatListItem
        @dblclick="doPlay(item.bvid)"
        @contextmenu.prevent="(e) => contextMenuRef?.open(e, item)"
      >
        <template #avatar>
          <CatImage :src="item.cover" :width="80" :height="80" />
        </template>
        <template #title>
          <span @click="doTitle(item.bvid)">{{ item.title }}</span>
        </template>
        <template #description>{{ item.bvid }}</template>
        <template #default>
          <span @click="doAuthor(item.authormid)">{{ item.author }}</span>
        </template>
        <template #suffix>{{ formatSeconds(item.duration) }}</template>
      </CatListItem>
    </template>
  </CatList>
</template>

<style lang="less">
span {
  text-decoration: none;
  cursor: pointer;
  &:hover {
    text-decoration: underline;
  }
}
</style>
